home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / rpg / crossfir.92 / crossfir / crossfire-0.92.5 / server / c_object.c < prev    next >
C/C++ Source or Header  |  1996-07-24  |  19KB  |  792 lines

  1. /*
  2.  * Object (handling) commands
  3.  *    ++Jam & Anipa
  4.  */
  5.  
  6. #include <global.h>
  7. #include <loader.h>
  8. #include <sproto.h>
  9.  
  10. /*
  11.  * Object id parsing functions
  12.  */
  13.  
  14. #define OBLINKMALLOC(p) if(!((p)=(objectlink *)malloc(sizeof(objectlink))))\
  15.                           fatal(OUT_OF_MEMORY);
  16.  
  17. #define ADD_ITEM(NEW,COUNT)\
  18.       if(!first) {\
  19.         OBLINKMALLOC(first);\
  20.         last=first;\
  21.       } else {\
  22.         OBLINKMALLOC(last->next);\
  23.         last=last->next;\
  24.       }\
  25.       last->next=NULL;\
  26.       last->ob=(NEW);\
  27.           last->id=(COUNT);
  28.  
  29. /* returns nonzero if the appropriate action can be
  30.  * done.  Really a stupid function - this should be handled in
  31.  * the calling function.
  32.  */
  33. static int may_do(object *op,object *ob,int state)
  34. {
  35.   if(!ob)
  36.     return 0;
  37.   switch(state)
  38.     {
  39.     case 0:            /* drop */
  40.       return (!QUERY_FLAG(ob,FLAG_NO_DROP) && !ob->invisible);
  41.  
  42.     case 1:            /* take */
  43.       return (can_pick(op,ob) && !ob->invisible);
  44.  
  45.     default:
  46.       return 0;
  47.     }
  48. }
  49.  
  50. static objectlink *parse_id(object *op,object *from, char *name, int state)
  51. {
  52.   objectlink *first=NULL,*last=NULL;
  53.   int count=0,plural=0;
  54.   char buf[MAX_BUF];
  55.  
  56.   while(name[0]==' ')        /* get rid of leading spaces ', ' */
  57.     name++;
  58.   if(strcmp(name,"all")==0)
  59.     {
  60.       while(from)
  61.     {
  62.       if(may_do(op,from,state))
  63.         {
  64.           ADD_ITEM(from,0);
  65.         }
  66.       from=from->below;
  67.     }
  68.       return first; 
  69.     }
  70.   if(strcmp(name,"unpaid")==0)
  71.     {
  72.       while(from)
  73.     {
  74.       if(QUERY_FLAG(from,FLAG_UNPAID) && may_do(op,from,state))
  75.         {
  76.           ADD_ITEM(from,0);
  77.         }
  78.       from=from->below;
  79.     }
  80.       return first; 
  81.     }
  82.   if((count=atoi(name))!=0)
  83.     name=strchr(name,' ');
  84.   else
  85.     if (op->contr->count>0 && op->contr->count<10000)
  86.       count=op->contr->count;
  87.   if(!name || strlen(name)==0 || count<0)
  88.     return NULL;
  89.   while(name[0]==' ')        /* get rid of leading spaces ', ' */
  90.     name++;
  91.   if(strlen(name)==0)
  92.     return NULL;
  93.   while(from)
  94.     {
  95.       if(may_do(op,from,state))
  96.     {
  97.       strcpy(buf,from->name);
  98.       if(QUERY_FLAG(from, FLAG_NEED_IE)) {
  99.         char *cp=strrchr(buf,'y');
  100.         if(cp!=NULL)
  101.           *cp='\0'; /* Strip the 'y' */
  102.         strcat(buf,"ies");
  103.       } else
  104.         strcat(buf,"s");
  105.       if(strcasecmp(name,from->name)==0 && count<2)    /* singular */
  106.         {
  107.           ADD_ITEM(from,1);
  108.           break;
  109.         }
  110.       else if(strcasecmp(name,buf)==0 && (count!=1 || plural)) /* plural */
  111.         {
  112.           plural=1;
  113.           ADD_ITEM(from,count);
  114.           count-=(from->nrof<1?1:from->nrof);
  115.           if(count<=0)
  116.         {
  117.           count=0;
  118.           break;
  119.         }
  120.         }
  121.       else if(strcasecmp(name,query_name(from))==0 && count==0)
  122.         {
  123.           ADD_ITEM(from,from->nrof);
  124.         }
  125.     }
  126.       from=from->below;
  127.     }
  128.   return first;
  129. }
  130.  
  131. objectlink *id(object *op,object *from,char *ids,int state)
  132. {
  133.   objectlink *first=NULL,*last=NULL,*tmp;
  134.   char *name;
  135.   if(from==NULL)
  136.     return NULL;
  137.   if(ids==NULL || !ids[0])
  138.     {
  139.       while(from && from->invisible && may_do(op, from, state))
  140.     from=from->below;
  141.       if(!from)
  142.     return NULL;
  143.       OBLINKMALLOC(first);
  144.       first->ob=from;
  145.       first->id=op->contr->count;
  146.       first->next=NULL;
  147.       return first;
  148.     }
  149.   name=strtok(ids,",");        /* pearls, gems, coins (split with commas) */
  150.   while(name)
  151.     {
  152.       if((tmp=parse_id(op,from,name,state)))
  153.     {
  154.       if(!first)
  155.         first=tmp;
  156.       else
  157.         last->next=tmp;
  158.       last=tmp;
  159.       while(last->next)    /* move to end of list */
  160.         last=last->next;
  161.     }
  162.       name=strtok(NULL,",");
  163.     }
  164.   if(first && first->next)    /* get rid of duplicates */
  165.     {
  166.       objectlink *pos,*prev;
  167.       pos=first;
  168.       while(pos)
  169.     {
  170.       tmp=pos->next;
  171.       prev=pos;
  172.       while(tmp)
  173.         {
  174.           if(tmp->ob == pos->ob)
  175.         {
  176.           if(tmp->id==0 || pos->id==0)
  177.             pos->id=0;
  178.           else
  179.             pos->id=pos->id + tmp->id;
  180.           prev->next=tmp->next;
  181.           free(tmp);
  182.           tmp=prev->next;
  183.         }
  184.           else
  185.         {
  186.           prev=tmp;
  187.           tmp=tmp->next;
  188.         }
  189.         }
  190.       pos=pos->next;
  191.     }
  192.     }
  193.   return first;
  194. }
  195.  
  196.  
  197. int command_uskill ( object *pl, char *params) {
  198.    if (!params) {
  199.         new_draw_info(NDI_UNIQUE, 0,pl, "Usage: use_skill <skill name>");
  200.         return 0;
  201.    }
  202.    return use_skill(pl,params);
  203. }
  204.  
  205. int command_rskill ( object *pl, char *params) {
  206.    if (!params) { 
  207.         new_draw_info(NDI_UNIQUE, 0,pl, "Usage: ready_skill <skill name>");
  208.         return 0;
  209.    }
  210.    return change_skill(pl,lookup_skill_by_name(params));
  211. }
  212.  
  213. int command_apply (object *op, char *params)
  214. {
  215.   if (!params) {
  216.     apply_below(op);
  217.     return 0;
  218.   }
  219.   apply_inventory(op);
  220.   /* By applying something what, the applied/unapplied state will change,
  221.    * so the window needs to be updated.
  222.    */
  223.   if (op->contr->show_what == show_applied || op->contr->show_what==show_unapplied)
  224.     draw_all_inventory(op);
  225.   return 0;
  226. }
  227.  
  228. /* Pick up commands follow */
  229. /* pl = player, op is the object to put tmp into, 
  230.  * tmp is the object to pick up, nrof is the number to
  231.  * pick up (0 means all of them)
  232.  */
  233. void pick_up_object (object *pl, object *op, object *tmp, int nrof)
  234. {
  235.     char buf[MAX_BUF];
  236.  
  237.     if(QUERY_FLAG(pl, FLAG_FLYING) && !QUERY_FLAG(pl, FLAG_WIZ)) {
  238.     new_draw_info(NDI_UNIQUE, 0,pl, "You are levitating, you can't reach the ground!");
  239.     return;
  240.     }
  241.     if(!can_pick(pl,tmp)) {
  242.     if (tmp->name!=NULL) {
  243.     sprintf(buf,"You can't pick up a %s", tmp->name);
  244.     new_draw_info(NDI_UNIQUE, 0,pl, buf);
  245.     }
  246.       else
  247.     new_draw_info(NDI_UNIQUE, 0,pl,"You can't take that!");
  248.       return;
  249.     }
  250.     if (QUERY_FLAG (tmp, FLAG_NO_DROP))
  251.     return;
  252.     if(QUERY_FLAG(tmp,FLAG_WAS_WIZ) && !QUERY_FLAG(pl, FLAG_WAS_WIZ)) {
  253.     new_draw_info(NDI_UNIQUE, 0,pl, "The object disappears in a puff of smoke!");
  254.     new_draw_info(NDI_UNIQUE, 0,pl, "It must have been an illusion.");
  255.     if (pl->contr->eric_server > 0)
  256.         esrv_del_item (pl->contr->eric_server, tmp->count);
  257.     remove_ob(tmp);
  258.     free_object(tmp);
  259.     return;
  260.     }
  261.     if(QUERY_FLAG(pl, FLAG_WAS_WIZ))
  262.     SET_FLAG(tmp, FLAG_WAS_WIZ);
  263.  
  264.     if(nrof && nrof != tmp->nrof) {
  265.     object *tmp2 = tmp;
  266.     tmp = get_split_ob (tmp, nrof);
  267.     if(!tmp) {
  268.         new_draw_info(NDI_UNIQUE, 0,pl, errmsg);
  269.         return;
  270.     }
  271.     /* Tell a client what happened rest of objects */
  272.     if (pl->contr->eric_server > 0)
  273.         if (QUERY_FLAG(tmp2, FLAG_REMOVED))
  274.         esrv_del_item (pl->contr->eric_server, tmp2->count);
  275.         else
  276.         esrv_send_item (pl, tmp2);
  277.     } else {
  278.     remove_ob(tmp); /* Unlink it */
  279.     }
  280.     if(QUERY_FLAG(tmp, FLAG_UNPAID))
  281.     (void) sprintf(buf,"%s will cost you %s.", query_name(tmp),
  282.         query_cost_string(tmp,op,F_BUY));
  283.     else
  284.     (void) sprintf(buf,"You pick up %s.", query_name(tmp));
  285.     new_draw_info(NDI_UNIQUE, 0,op,buf);
  286.  
  287.     tmp = insert_ob_in_ob(tmp, op);
  288.     if(pl->type!=PLAYER) return;
  289.     if (pl->contr->eric_server > 0) {
  290.     esrv_send_item (pl, tmp);
  291.     } else {
  292.     pl->contr->last_used=tmp;
  293.     pl->contr->last_used_id=tmp->count;
  294.  
  295.     draw_inventory(pl);
  296.  
  297.     if (pl->container)
  298.         draw_look (pl);
  299.     }
  300. }
  301.  
  302.  
  303. void pick_up(object *op,object *alt) 
  304. /* modified slightly to allow monsters use this -b.t. 5-31-95 */
  305. {
  306.     object *tmp=NULL;
  307.     int count;
  308.  
  309.     if(alt)
  310.     tmp=alt;
  311.     else if(op->below==NULL || !can_pick(op, tmp)) {
  312.     new_draw_info(NDI_UNIQUE, 0,op,"There is nothing to pick up here.");
  313.     return;
  314.     } else
  315.     tmp=op->below;
  316.  
  317.     if (op->type==PLAYER && op->contr->count && op->contr->count <tmp->nrof)
  318.     count=op->contr->count;
  319.     else
  320.     count=tmp->nrof;
  321.  
  322.     /* container is open, so use it */
  323.     if (op->container) {
  324.     alt = op->container;
  325.     if (alt != tmp->env && !sack_can_hold (op, alt, tmp,count))
  326.         return;
  327.     } else {
  328.     for (alt=op->inv; alt; alt=alt->below)
  329.         if (alt->type==CONTAINER && QUERY_FLAG(alt, FLAG_APPLIED) &&
  330.         alt->race && alt->race==tmp->race &&
  331.         sack_can_hold (NULL, alt, tmp,count))
  332.         break;  /* perfect match */
  333.     
  334.     if (!alt)
  335.         for (alt=op->inv; alt; alt=alt->below)
  336.         if (alt->type==CONTAINER && QUERY_FLAG(alt, FLAG_APPLIED) &&
  337.             sack_can_hold (NULL, alt, tmp,count))
  338.             break;  /* General container comes next */
  339.     if (!alt)
  340.         alt = op; /* No free containers */
  341.     }
  342.     if(tmp->env == alt) {
  343.     /* here it could be possible to check rent,
  344.      * if someone wants to implement it
  345.      */
  346.     alt = op;
  347.     }
  348. #ifdef PICKUP_DEBUG
  349.     printf ("Pick_up(): %s picks %s (%d) and inserts it %s.\n",op->name, tmp->name,  op->contr->count, alt->name);
  350. #endif
  351.     if(op->type==PLAYER) { 
  352.        pick_up_object(op, alt, tmp, op->contr->count);
  353.        op->contr->count=0;
  354.     } else 
  355.        pick_up_object(op, alt, tmp, tmp->nrof);
  356. }
  357.  
  358.  
  359. int command_take (object *op, char *params)
  360. {
  361.     object *tmp=op->below, *next;
  362.  
  363.     if (tmp==NULL) {
  364.     new_draw_info(NDI_UNIQUE, 0,op,"Nothing to take!");
  365.     return 0;
  366.     }
  367.  
  368.     /* Makes processing easier */
  369.     if (params && *params=='\0') params=NULL;
  370.  
  371.     op->contr->freeze_inv=1;
  372.     op->contr->freeze_look=1;
  373.     while (tmp) {
  374.     next=tmp->below;
  375.  
  376.     if (tmp->invisible) {
  377.         tmp=next;
  378.         continue;
  379.     }
  380.     /* This following two if and else if could be merged into line
  381.      * but that probably will make it more difficult to read, and
  382.      * not make it any more efficient
  383.      */
  384.     if (params && !strncasecmp(params, tmp->name, strlen(params))) {
  385.         pick_up(op, tmp);
  386.     }
  387.     else if (can_pick(op, tmp) && !params) {
  388.         pick_up(op,tmp);
  389.         break;
  390.     }
  391.     tmp=next;
  392.     }
  393.     if (!params && !tmp) {
  394.     for (tmp=op->below; tmp!=NULL; tmp=tmp->next)
  395.         if (!tmp->invisible) {
  396.         char buf[MAX_BUF];
  397.         sprintf(buf,"You can't pick up a %s",
  398.             tmp->name? tmp->name:"null");
  399.         new_draw_info(NDI_UNIQUE, 0,op, buf);
  400.         break;
  401.         }
  402.     if (!tmp) new_draw_info(NDI_UNIQUE, 0,op, "There is nothing to pick up.");
  403.     }
  404.  
  405.     op->contr->freeze_inv=0;
  406.     op->contr->freeze_look=0;
  407.     draw_inventory(op);
  408.     draw_look(op);
  409.     return 0;
  410. }
  411.  
  412.  
  413. /*
  414.  *  This function was part of drop, now is own function. 
  415.  *  Player 'op' tries to put object 'tmp' into sack 'sack', 
  416.  *  if tmp is non zero, then nrof objects is tried to put into sack. 
  417.  */
  418. void put_object_in_sack (object *op, object *sack, object *tmp, long nrof) 
  419. {
  420.     object *tmp2;
  421.     char buf[MAX_BUF];
  422.  
  423.     if (sack==tmp) return;    /* Can't put an object in itself */
  424.     if (sack->type != CONTAINER) {
  425.       new_draw_info_format(NDI_UNIQUE, 0,op,
  426.     "%s is not a container.", query_name(sack));
  427.       return;
  428.     }
  429.     if (QUERY_FLAG(tmp,FLAG_STARTEQUIP)) {
  430.       new_draw_info_format(NDI_UNIQUE, 0,op,
  431.     "You cannot put %s in the container.", query_name(tmp));
  432.       return;
  433.     }
  434.     if (tmp->type == CONTAINER && tmp->inv) {
  435.  
  436.       /* Eneq(@csd.uu.se): If the object to be dropped is a container 
  437.        * we instead move the contents of that container into the active
  438.        * container, this is only done if the object has something in it. 
  439.        */
  440.  
  441.       sprintf (buf, "You move the items from %s into ", query_name(tmp));
  442.       strcat (buf,  query_name(op->container));
  443.       strcat (buf, ".");
  444.       new_draw_info(NDI_UNIQUE, 0,op, buf);
  445.       for (tmp2 = tmp->inv; tmp2; tmp2 = tmp) {
  446.       tmp = tmp2->below;
  447.     if (sack_can_hold(op, op->container, tmp2,tmp2->nrof))
  448.       put_object_in_sack (op, sack, tmp2, 0);
  449.     else {
  450.       sprintf(buf,"Your %s fills up.", query_name(op->container));
  451.       new_draw_info(NDI_UNIQUE, 0,op, buf);
  452.       break;
  453.     }
  454.       }
  455.       return;
  456.     }
  457.  
  458.     if (! sack_can_hold (op, sack, tmp,(nrof?nrof:tmp->nrof)))
  459.       return;
  460.  
  461.     /* Small hack to avoid autojoining in apply_special(): */
  462.     if(QUERY_FLAG(tmp, FLAG_APPLIED)) {
  463.       int nrof = tmp->nrof, a;
  464.       tmp->nrof = 0;
  465.       a = apply_special(op,tmp);
  466.       tmp->nrof = nrof;
  467.       if (a)
  468.       return;
  469.     }
  470.  
  471.     if (nrof && tmp->nrof != nrof) {
  472.       object *tmp2 = tmp;
  473.       tmp = get_split_ob (tmp, nrof);
  474.       if(!tmp) {
  475.       new_draw_info(NDI_UNIQUE, 0,op, errmsg);
  476.       return;
  477.       }
  478.       /* Tell a client what happened other objects */ 
  479.       if (op->contr->eric_server > 0)
  480.       if (QUERY_FLAG(tmp2, FLAG_FREED))
  481.           esrv_del_item (op->contr->eric_server, tmp2->count);
  482.       else
  483.           esrv_send_item (op, tmp2);
  484.     } else
  485.       remove_ob(tmp);
  486.  
  487.     sprintf(buf, "You put %s in ", query_name(tmp));
  488.     strcat (buf, query_name(sack));
  489.     strcat (buf, ".");
  490.     tmp = insert_ob_in_ob(tmp, sack);
  491.     new_draw_info(NDI_UNIQUE, 0,op,buf);
  492.     if (op->contr->eric_server > 0) {
  493.       esrv_send_item (op, tmp);
  494.     } else {
  495.       draw_look(op);
  496.       draw_inventory(op);
  497.     }
  498.     fix_player(op); /* This is overkill, fix_player() is called somewhere */ 
  499.           /* in object.c */
  500. }
  501.  
  502. /*
  503.  *  This function was part of drop, now is own function. 
  504.  *  Player 'op' tries to drop object 'tmp', if tmp is non zero, then
  505.  *  nrof objects is tried to dropped. 
  506.  */
  507. void drop_object (object *op, object *tmp, long nrof) 
  508. {
  509.     char buf[MAX_BUF];
  510.     object *floor;
  511.   
  512.     if (QUERY_FLAG(tmp, FLAG_NO_DROP)) {
  513. #if 0
  514.       /* Eneq(@csd.uu.se): Objects with NO_DROP defined can't be dropped. */
  515.       new_draw_info(NDI_UNIQUE, 0,op, "This item can't be dropped.");
  516. #endif
  517.       return;
  518.     }
  519.  
  520.     /* Small hack to avoid autojoining in apply_special(): */
  521.     if(QUERY_FLAG(tmp, FLAG_APPLIED)) {
  522.       int nrof = tmp->nrof,a;
  523.       tmp->nrof = 0;
  524.       a = apply_special (op, tmp);
  525.       tmp->nrof = nrof;
  526.       if (a)        /* can't unapply it */
  527.       return;
  528.     }
  529.  
  530.     if(nrof && tmp->nrof != nrof) {
  531.       object *tmp2 = tmp;
  532.       tmp = get_split_ob (tmp, nrof);
  533.       if(!tmp) {
  534.       new_draw_info(NDI_UNIQUE, 0,op, errmsg);
  535.       return;
  536.       }
  537.       /* Tell a client what happened rest of objects */ 
  538.       if (op->contr->eric_server > 0)
  539.       if (QUERY_FLAG(tmp2, FLAG_FREED))
  540.           esrv_del_item (op->contr->eric_server, tmp->count);
  541.       else
  542.           esrv_send_item (op, tmp);
  543.     } else
  544.       remove_ob (tmp);
  545.  
  546.     if (QUERY_FLAG (tmp, FLAG_STARTEQUIP)) {
  547.       sprintf(buf,"You drop %s.", query_name(tmp));
  548.       new_draw_info(NDI_UNIQUE, 0,op,buf);
  549.       new_draw_info(NDI_UNIQUE, 0,op,"The gods who lent it to you retrieves it.");
  550.       if (op->contr->eric_server > 0)
  551.       esrv_del_item (op->contr->eric_server, tmp->count);
  552.       free_object(tmp);
  553.       fix_player(op);
  554.       return;
  555.     }
  556.  
  557. /*  If SAVE_INTERVAL is commented out, we never want to save 
  558.  *  the player here. 
  559.  */
  560. #ifdef SAVE_INTERVAL
  561.     if (!QUERY_FLAG(tmp, FLAG_UNPAID) && 
  562.       (tmp->nrof ? tmp->value * tmp->nrof : tmp->value > 2000))
  563. #if SAVE_INTERVAL
  564.       if((op->contr->last_save_time + SAVE_INTERVAL) <= time(NULL)) {
  565.       save_player(op, 1);
  566.       op->contr->last_save_time = time(NULL);
  567. }
  568. #else
  569.     save_player(op,1); /* To avoid cheating */
  570. #endif
  571. #endif /* SAVE_INTERVAL */
  572.     
  573.     D_LOCK(op);
  574.  
  575.     floor = get_map_ob (op->map, op->x, op->y);
  576.     if( floor && floor->type == SHOP_FLOOR && 
  577.        !QUERY_FLAG(tmp, FLAG_UNPAID) && tmp->type != MONEY)
  578.       sell_item(tmp,op);
  579.  
  580.     tmp->x = op->x;
  581.     tmp->y = op->y;
  582.     insert_ob_in_map(tmp, op->map);
  583.     remove_ob(op);
  584.     insert_ob_in_map(op, op->map);
  585.     D_UNLOCK(op);
  586.  
  587.     if (op->contr->eric_server > 0) {
  588.       esrv_send_item (op, tmp);
  589.     } else {
  590.       draw_look(op);
  591.       draw_inventory(op);
  592.     }
  593.     fix_player(op); /* This is overkill, fix_player() is called somewhere */ 
  594.             /* in object.c */
  595. #ifdef USE_LIGHTING
  596.     if(tmp->glow_radius>0) remove_light_from_list(tmp,op);
  597. #endif
  598. }
  599.  
  600. void drop(object *op, object *tmp) 
  601. {
  602.     while(tmp!=NULL && tmp->invisible)
  603.       tmp=tmp->below;
  604.  
  605.     if (tmp==NULL) {
  606.       new_draw_info(NDI_UNIQUE, 0,op,"You don't have anything to drop.");
  607.       return;
  608.     }
  609.     if (QUERY_FLAG(tmp, FLAG_INV_LOCKED)) {
  610.       new_draw_info(NDI_UNIQUE, 0,op,"This item is locked");
  611.       return;
  612.     } 
  613.     if (QUERY_FLAG(tmp, FLAG_NO_DROP)) {
  614. #if 0
  615.       /* Eneq(@csd.uu.se): Objects with NO_DROP defined can't be dropped. */
  616.       new_draw_info(NDI_UNIQUE, 0,op, "This item can't be dropped.");
  617. #endif
  618.       return;
  619.     }
  620.  
  621.     if (op->contr->last_used==tmp && op->contr->last_used_id == tmp->count) {
  622.       object *n=NULL;
  623.       if(tmp->below != NULL)
  624.       n = tmp->below;
  625.       else if(tmp->above != NULL)
  626.       n = tmp->above;
  627.       op->contr->last_used = n;
  628.       if (n != NULL)
  629.       op->contr->last_used_id = n->count;
  630.       else
  631.       op->contr->last_used_id = 0;
  632.     }
  633.  
  634.     if (op->container) {
  635.       put_object_in_sack (op, op->container, tmp, op->contr->count);
  636.     } else {
  637.       drop_object (op, tmp, op->contr->count);
  638.     }
  639.     op->contr->count = 0;
  640. }
  641.  
  642.  
  643.  
  644. /* Command will drop all items that have not been locked */
  645. int command_dropall (object *op, char *params) {
  646.  
  647.   object * curinv, *nextinv;
  648.   
  649.   if(op->inv == NULL) {
  650.     new_draw_info(NDI_UNIQUE, 0,op,"Nothing to drop!");
  651.     return 0;
  652.   }
  653.   
  654.   curinv = op->inv;
  655.   op->contr->freeze_inv=1;
  656.   op->contr->freeze_look=1;
  657.  
  658.   /* 
  659.     This is the default.  Drops everything not locked or considered
  660.     not something that should be dropped.
  661.   */
  662.   /*
  663.     Care must be taken that the next item pointer is not to money as
  664.     the drop() routine will do unknown things to it when dropping
  665.     in a shop. --Tero.Pelander@utu.fi
  666.   */
  667.  
  668.   if(params==NULL) {
  669.     while(curinv != NULL) {
  670.       nextinv = curinv->below;
  671.       while (nextinv && nextinv->type==MONEY)
  672.     nextinv = nextinv->below;
  673.       if(! QUERY_FLAG(curinv,FLAG_INV_LOCKED) && curinv->type != MONEY &&
  674.      curinv->type != FOOD && curinv->type != KEY && 
  675.      curinv->type != SPECIAL_KEY && curinv->type != GEM &&
  676.      !curinv->invisible &&
  677.      (curinv->type!=CONTAINER || op->container!=curinv))
  678.     {
  679.      drop(op,curinv);
  680.        }
  681.       curinv = nextinv;
  682.     }
  683.   }
  684.  
  685.   else if(strcmp(params, "weapons") == 0) {
  686.     while(curinv != NULL) {
  687.       nextinv = curinv->below;
  688.       while (nextinv && nextinv->type==MONEY)
  689.     nextinv = nextinv->below;
  690.       if(! QUERY_FLAG(curinv,FLAG_INV_LOCKED) && ((curinv->type == WEAPON) ||
  691.      (curinv->type == BOW) || (curinv->type == ARROW)))
  692.     {
  693.       drop(op,curinv);
  694.     }
  695.       curinv = nextinv;
  696.     }
  697.   }
  698.   
  699.   else if(strcmp(params, "armor") == 0 || strcmp(params, "armour") == 0) {
  700.     while(curinv != NULL) {
  701.       nextinv = curinv->below;
  702.       while (nextinv && nextinv->type==MONEY)
  703.     nextinv = nextinv->below;
  704.       if(! QUERY_FLAG(curinv,FLAG_INV_LOCKED) && ((curinv->type == ARMOUR) ||
  705.      curinv->type == SHIELD || curinv->type==HELMET))
  706.     {
  707.       drop(op,curinv);
  708.     }
  709.       curinv = nextinv;
  710.     }
  711.   }
  712.  
  713.   else if(strcmp(params, "misc") == 0) {
  714.     while(curinv != NULL) {
  715.       nextinv = curinv->below;
  716.       while (nextinv && nextinv->type==MONEY)
  717.     nextinv = nextinv->below;
  718.       if(! QUERY_FLAG(curinv,FLAG_INV_LOCKED) && ! QUERY_FLAG(curinv,FLAG_APPLIED)) {
  719.     switch(curinv->type) {
  720.     case HORN:
  721.     case BOOK:
  722.     case SPELLBOOK:
  723.     case GIRDLE:
  724.     case AMULET:
  725.     case RING:
  726.     case CLOAK:
  727.     case BOOTS:
  728.     case GLOVES:
  729.     case BRACERS:
  730.     case SCROLL:
  731.     case ARMOUR_IMPROVER:
  732.     case WEAPON_IMPROVER:
  733.     case WAND:
  734.     case ROD:
  735.     case POTION:
  736.       drop(op,curinv);
  737.       curinv = nextinv;
  738.       break;
  739.     default:
  740.       curinv = nextinv;
  741.       break;
  742.     }
  743.       }
  744.       curinv = nextinv;
  745.     }
  746.   }
  747.  
  748.   op->contr->freeze_inv=0;
  749.   op->contr->freeze_look=0;
  750.   draw_all_inventory(op);
  751.   draw_look(op);
  752.   return 0;
  753. }
  754.     
  755.  
  756. int command_drop (object *op, char *params)
  757. {
  758.   objectlink *list,*tmp;
  759.   list=id(op,op->inv,params,0);
  760.   if(!list)
  761.     {
  762.       new_draw_info(NDI_UNIQUE, 0,op,"Nothing to drop!");
  763.       return 0;
  764.     }
  765.   op->contr->freeze_inv=1;
  766.   op->contr->freeze_look=1;
  767.   while(list)
  768.     {
  769.       op->contr->count=list->id;
  770.       drop(op,list->ob);
  771.       tmp=list->next;
  772.       free(list);
  773.       list=tmp;
  774.     }
  775.   op->contr->freeze_inv=0;
  776.   op->contr->freeze_look=0;
  777.   op->contr->count=0;
  778.   draw_all_inventory(op);
  779.   draw_look(op);
  780.   return 0;
  781. }
  782.  
  783. int command_examine (object *op, char *params)
  784. {
  785.   if (!params)
  786.     examine(op,op->below);
  787.   else
  788.     examine(op,op->inv);
  789.   return 0;
  790. }
  791.  
  792.